home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / trmatch < prev    next >
Encoding:
Internet Message Format  |  1987-02-12  |  10.9 KB

  1. Subject:  v08i063:  Syntax-checker for *roff
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: Kamal Al-Yahya <kamal@hanauma.STANFORD.EDU>
  6. Mod.sources: Volume 8, Issue 63
  7. Archive-name: trmatch
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If all goes well, you will see the message "End of shell archive."
  13. # Contents:  Makefile trmatch.1 trmatch.c
  14. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  15. echo shar: extracting "'Makefile'" '(84 characters)'
  16. if test -f 'Makefile' ; then 
  17.   echo shar: will not over-write existing file "'Makefile'"
  18. else
  19. sed 's/^X//' >Makefile <<'@//E*O*F Makefile//'
  20. X# Makefile for trmatch.
  21. X
  22. XCFLAGS    = -O
  23. Xtrmatch:
  24. X    $(CC) $(CFLAGS) -o trmatch trmatch.c
  25. @//E*O*F Makefile//
  26. if test 84 -ne "`wc -c <'Makefile'`"; then
  27.     echo shar: error transmitting "'Makefile'" '(should have been 84 characters)'
  28. fi
  29. fi # end of overwriting check
  30. echo shar: extracting "'trmatch.1'" '(841 characters)'
  31. if test -f 'trmatch.1' ; then 
  32.   echo shar: will not over-write existing file "'trmatch.1'"
  33. else
  34. sed 's/^X//' >trmatch.1 <<'@//E*O*F trmatch.1//'
  35. X.TH trmatch L 7/10/86
  36. X.UC 4
  37. X.SH NAME
  38. Xtrmatch \- checks matching in troff documents.
  39. X.SH SYNOPSIS
  40. X.B trmatch
  41. X.I filename
  42. X.SH DESCRIPTION
  43. X.I Trmatch
  44. Xgives error messages if it detects unmatched
  45. Xbraces, brackets, parentheses, equations, and
  46. Xdollar signs in troff documents.
  47. XError messages are sent to the standard error.
  48. X.br
  49. XEscaped braces, brackets, parentheses, and dollar signs are not counted.
  50. XText and equations are checked separately.
  51. XIt takes equations to be delimited by .EQ and .EN.
  52. XIf a ``define'' occurs in the equation, the line containing
  53. Xthe ``define'' is not checked (since it is bound to have unmatches).
  54. X.SH DIAGNOSTICS
  55. XDisplayed equations that are started and ended by user-defined
  56. Xcommands are regarded as text and matching is not checked
  57. Xseparately.
  58. X.SH SEE ALSO
  59. Xtexmatch(L).
  60. X.SH AUTHOR
  61. XKamal Al-Yahya, Stanford University
  62. X
  63. @//E*O*F trmatch.1//
  64. if test 841 -ne "`wc -c <'trmatch.1'`"; then
  65.     echo shar: error transmitting "'trmatch.1'" '(should have been 841 characters)'
  66. fi
  67. fi # end of overwriting check
  68. echo shar: extracting "'trmatch.c'" '(8152 characters)'
  69. if test -f 'trmatch.c' ; then 
  70.   echo shar: will not over-write existing file "'trmatch.c'"
  71. else
  72. sed 's/^X//' >trmatch.c <<'@//E*O*F trmatch.c//'
  73. X/*
  74. X * trmatch: checks matching parantheses, braces, brackets, and dollar signs.
  75. X *        for troff documents
  76. X *
  77. X * to compile:  cc trmatch.c -lsep -o trmatch
  78. X */
  79. X
  80. Xchar *documentation[] = {
  81. X" NAME",
  82. X"        trmatch",
  83. X"",
  84. X" SYNTAX",
  85. X"        trmatch [parameters] [inputfiles]",
  86. X"",
  87. X"        parameters:",
  88. X"              in=filename       filename is the input file",
  89. X"                                (Default: in=stdin)",
  90. X"",
  91. X};
  92. X
  93. X/* Author:    Kamal Al-Yahya        7/20/1986 */
  94. X
  95. Xint    doclength = { sizeof documentation/sizeof documentation[0] };
  96. X
  97. X#include        <stdio.h>
  98. X#include        <sys/ioctl.h>
  99. X#include        <sgtty.h>
  100. X
  101. Xchar string[80],filename[80];
  102. Xstruct sgttyb ttystat;
  103. Xstatic char *name="trmatch";
  104. Xextern char *strcpy(), *mktemp();
  105. X
  106. X/* for getpar */
  107. Xint xargc;
  108. Xchar **xargv;
  109. X
  110. Xmain(argc,argv)
  111. Xint argc; 
  112. Xchar *argv[];
  113. X{
  114. X    FILE *temp;
  115. X    register char *cptr;
  116. X    int piped_in;
  117. X    int i;
  118. X
  119. X    /* If no arguments, and not in a pipeline, self document */
  120. X    piped_in = ioctl ((fileno (stdin)), TIOCGETP, &ttystat);
  121. X    if (argc == 1 && !piped_in)
  122. X        {
  123. X        for( i=0; i<doclength; i++)
  124. X            printf("%s\n",documentation[i]);
  125. X        exit (0);
  126. X        }
  127. X
  128. X    /* process getpar parameters */
  129. X    xargc = argc;
  130. X    xargv = argv;
  131. X
  132. X     /* first process pipe input */
  133. X    if(piped_in)
  134. X        {
  135. X        troff_match(stdin);
  136. X        fprintf(stderr,"\n");
  137. X        }
  138. X
  139. X#ifdef GETPAR
  140. X    /* next process in=inputfiles */
  141. X    if(getpar_("in","s",string))
  142. X        {
  143. X        sscanf(string,"%s",filename);
  144. X        if((temp=fopen(filename,"r")) != NULL)
  145. X            {
  146. X            fprintf(stderr,"%s:\n",filename);
  147. X            troff_match(temp);
  148. X            fprintf(stderr,"\n");
  149. X            fclose(temp);
  150. X            }
  151. X        else
  152. X            fprintf(stderr,"%s: Cannot open %s\n",name,filename);
  153. X        }
  154. X#endif    /* GETPAR */
  155. X
  156. X    /*
  157. X     * finally process input line for non-getpar arguments and assume
  158. X     * they are also input files
  159. X     */
  160. X    for (xargc--,xargv++; xargc; xargc--,xargv++)
  161. X        {
  162. X        cptr = *xargv; 
  163. X        if( *cptr=='-' ) continue; /* this is a flag */
  164. X        while (*cptr)
  165. X            {
  166. X#ifdef    GETPAR
  167. X            if (*cptr == '=')  break; /* this is for getpar */
  168. X#endif    /* GETPAR */
  169. X            cptr++;
  170. X            }       
  171. X        if (*cptr)  continue;
  172. X        cptr = *xargv;
  173. X        if((temp=fopen(cptr,"r")) != NULL)
  174. X            {
  175. X            fprintf(stderr,"%s:\n",cptr);
  176. X            troff_match(temp);
  177. X            fprintf(stderr,"\n");
  178. X            fclose(temp);
  179. X            }
  180. X        else
  181. X            fprintf(stderr,"%s: Cannot open %s\n",name,cptr);
  182. X        }
  183. X
  184. X}
  185. X
  186. Xtroff_match(fp)            /* check matching */
  187. XFILE *fp;
  188. X{
  189. X
  190. Xint l=1;            /* line counter */
  191. Xint ld=0;            /* single left dollar signs */
  192. Xint rd=0;            /* single right dollar signs */
  193. Xint eq=0;            /* eq=1 : equation (delimeted by .EQ and .EN) */
  194. Xint lp=0;            /* left parantheses */
  195. Xint rp=0;            /* right parantheses */
  196. Xint lb=0;            /* left brackets */
  197. Xint rb=0;            /* right brackets */
  198. Xint lbr=0;            /* left braces */
  199. Xint rbr=0;            /* right braces */
  200. Xint c=' ';            /* current character */
  201. Xint c1=' ';            /* previous character */
  202. Xint lbrl=0;            /* line number of left braces */
  203. Xint lbl=0;            /* line number of left bracket */
  204. Xint lpl=0;            /* line number of left parentheses */
  205. Xint ldl=1;            /* line number of left single dollar sign */
  206. Xint eql=1;            /* line number at which equation is started */
  207. Xint war=0;            /* warning status */
  208. Xint esc=0;            /* escape status */
  209. X
  210. Xwhile ((c =getc(fp)) != EOF)
  211. X    {
  212. Xtop:
  213. X    switch(c)
  214. X        {
  215. X        case '\n':
  216. X            l++;        /* increment line counter */
  217. X/* check to see if a single dollar sign is not closed at the same line */
  218. X            if (ld == 1 && war == 0 && c1 != '\\')
  219. X                {
  220. X                fprintf(stderr,"line %d: WARNING: single dollar sign is not closed on the same line\n",l-1);
  221. X                war=1;        /* warning has been given */
  222. X                }
  223. X            esc = 0;        /* escape status */
  224. X            break;
  225. X        case '{':
  226. X            if (esc == 0)
  227. X                {
  228. X                lbr++;
  229. X                if (lbrl == 0) lbrl=l;
  230. X                }
  231. X            esc = 0;        /* escape status */
  232. X            break;
  233. X        case '}':
  234. X            if (esc == 0)    rbr++;
  235. X            if (rbr > lbr)
  236. X                {
  237. X                fprintf(stderr,"line %d: unmatched braces\n",l);
  238. X                rbr--;        /* reset the count */
  239. X                }
  240. X            if (lbr == rbr)    lbrl=0;
  241. X            esc = 0;        /* escape status */
  242. X            break;
  243. X        case '[':
  244. X            if (esc == 0)
  245. X                {
  246. X                lb++;
  247. X                if (lbl == 0) lbl=l;
  248. X                }
  249. X            esc = 0;        /* escape status */
  250. X            break;
  251. X        case ']':
  252. X            if (esc == 0)    rb++;
  253. X            else        esc = 0;    /* escape status */
  254. X            if (rb > lb)
  255. X                {
  256. X                 fprintf(stderr,"line %d: unmatched brackets\n",l);
  257. X                rb--;        /* reset the count */
  258. X                }
  259. X            if (lb == rb)    lbl=0;
  260. X            esc = 0;        /* escape status */
  261. X            break;
  262. X        case '(':
  263. X            if (esc == 0)
  264. X                {
  265. X                lp++;
  266. X                if (lpl == 0) lpl=l;
  267. X                }
  268. X            esc = 0;        /* escape status */
  269. X            break;
  270. X        case ')':
  271. X            if (esc == 0)    rp++;
  272. X            if (rp > lp)
  273. X                {
  274. X               fprintf(stderr,"line %d: unmatched parentheses\n",l);
  275. X                rp--;        /* reset the count */
  276. X                }
  277. X            if (lp == rp)    lpl=0;
  278. X            esc = 0;        /* escape status */
  279. X            break;
  280. X        case '$':
  281. X            if (esc == 1)        /* escaped dollar sign */
  282. X                {
  283. X                c=' ';        /* reset the dollar sign */
  284. X                esc = 0;    /* escape status */
  285. X                break;
  286. X                }
  287. X            if (ld == 1)    rd=1;    /* right dollar sign */
  288. X            else
  289. X                {
  290. X                ld=1;     /* left dollar sign */
  291. X                ldl=l;    /* line number */
  292. X                war=0;    /* no warning hs been given */
  293. X                }
  294. X            esc = 0;        /* escape status */
  295. X            break;
  296. X        case '.':
  297. X            if (c1 == '\n' || l == 1)    /* troff command */
  298. X                {
  299. X                /* see if it is .EQ */
  300. X                c1=getc(fp);
  301. X                if (c1 == '\n')
  302. X                    {
  303. X                    esc=0;
  304. X                    l++;
  305. X                    break;
  306. X                    }
  307. X                c=getc(fp);
  308. X                if (c == '\n')
  309. X                    {
  310. X                    esc=0;
  311. X                    l++;
  312. X                    break;
  313. X                    }
  314. X                if (c1 == 'E' && c == 'Q')
  315. X                    {
  316. X                    if (eq == 1)
  317. X    fprintf(stderr,"line %d: equation started while equation at line %d is still open\n",l,eql);
  318. X                    eq=1;    /* beginning of equation */
  319. X                    eql=l;    /* line number */
  320. X/* Give warning about unclosed openings */
  321. X                    if ((lbr-rbr) > 0)
  322. X    fprintf(stderr,"line %d: %d unclosed braces before equation, first brace opened at line %d\n",eql,lbr-rbr,lbrl);
  323. X                    if ((lb-rb) > 0)
  324. X    fprintf(stderr,"line %d: %d unclosed brackets before equation, first bracket opened at line %d\n",eql,lb-rb,lbl);
  325. X                    if ((lp-rp) > 0)
  326. X    fprintf(stderr,"line %d: %d unclosed parentheses before equation, first parenthesis opened at line %d\n",eql,lp-rp,lpl);
  327. X/* clear registers */
  328. X                    lp=0; lb=0; lbr=0;
  329. X                    rp=0; rb=0; rbr=0;
  330. X                    lpl=0; lbrl=0; lbl=0;
  331. X                    }
  332. X                else if (c1 == 'E' && c == 'N')
  333. X                    {
  334. X                    if (eq == 0)
  335. X    fprintf(stderr,"line %d: equation ends but no equation beginning\n",l);
  336. X/* Give warning about unclosed openings */
  337. X                    if ((lbr-rbr) > 0)
  338. X    fprintf(stderr,"line %d: %d unclosed braces in equation\n",eql,lbr-rbr);
  339. X                    if ((lb-rb) > 0)
  340. X    fprintf(stderr,"line %d: %d unclosed brackets in equation\n",eql,lb-rb);
  341. X                    if ((lp-rp) > 0)
  342. X    fprintf(stderr,"line %d: %d unclosed parentheses in equation\n",eql,lp-rp);
  343. X/* clear registers */
  344. X                    lp=0; lb=0; lbr=0;
  345. X                    rp=0; rb=0; rbr=0;
  346. X                    lpl=0; lbrl=0; lbl=0;
  347. X                    eq=0;    /* end of equation */
  348. X                    }
  349. X                else
  350. X                    while ((c = getc(fp)) != EOF)
  351. X                        if (c == '\n')
  352. X                            {
  353. X                            l++;
  354. X                            break;
  355. X                            }
  356. X                }
  357. X            esc = 0;        /* escape status */
  358. X            break;
  359. X        case 'd':
  360. X/* check for possible define; ignore define lines */
  361. X            esc = 0;
  362. X            if (eq == 1 && c1 == '\n')
  363. X                {
  364. X                if ((c = getc(fp)) == 'e')
  365. X                if ((c = getc(fp)) == 'f')
  366. X                if ((c = getc(fp)) == 'i')
  367. X                if ((c = getc(fp)) == 'n')
  368. X                if ((c = getc(fp)) == 'e')
  369. X                    while ((c = getc(fp)) != EOF)
  370. X                        if (c == '\n')    break;
  371. X                if (c == '\n')    l++;
  372. X                }
  373. X/* if we grapped a character not in the word "define", go to switch
  374. X   to parse the rest of the line */
  375. X            if (!(c=='d'||c=='e'||c=='f'||c=='i'||c=='n'||c=='\n'))
  376. X                        goto top;
  377. X            c1 = ' ';
  378. X            esc = 0;        /* escape status */
  379. X            break;
  380. X        case '\\':
  381. X/* check escape status */
  382. X            if (c1 == '\\' && esc == 1)    esc = 0;
  383. X            else        esc = 1;
  384. X            break;
  385. X        default:
  386. X            esc = 0;        /* escape status */
  387. X            break;
  388. X        }
  389. X    c1=c;                    /* update previous character */
  390. X    if (ld == 1 && rd == 1)
  391. X        {ld=0.;        rd=0.;}        /* matched dollar signs */
  392. X    }
  393. Xif ((lbr-rbr) > 0)
  394. X    fprintf(stderr,"file ends: %d unclosed left braces, first opened at line %d \n",lbr-rbr,lbrl);
  395. Xif ((lb-rb) > 0)
  396. X    fprintf(stderr,"file ends: %d unclosed left brackets, first opened at line %d \n",lb-rb,lbl);
  397. Xif ((lp-rp) > 0)
  398. X    fprintf(stderr,"file ends: %d unclosed left parentheses, first opened at line %d \n",lp-rp,lpl);
  399. Xif (ld == 1)
  400. X    fprintf(stderr,"file ends: single dollar sign opened at line %d unclosed\n",ldl);
  401. Xif (eq == 1)
  402. X    fprintf(stderr,"file ends: equation started at line %d not closed\n",eql);
  403. X}
  404. @//E*O*F trmatch.c//
  405. if test 8152 -ne "`wc -c <'trmatch.c'`"; then
  406.     echo shar: error transmitting "'trmatch.c'" '(should have been 8152 characters)'
  407. fi
  408. fi # end of overwriting check
  409. echo shar: "End of shell archive."
  410. exit 0
  411.